﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using BuyTicket.Models;
using BuyTicket.Views;

namespace BuyTicket.Service
{
    class BuyTicketService
    {
        static HttpResponse m_Response = null;

        static X509CertificateCollection m_X509 = null;

        static BuyTicketService()
        {
            m_X509 = new X509CertificateCollection(){
                new X509Certificate(Properties.Resources.x509)
            };
        }

        static string m_Cookies = string.Empty;

        public static string Cookies
        {
            get { return m_Cookies; }
        }

        public static void Navigate(string url)
        {
            WebBrowserWindow window = new WebBrowserWindow();
            window.Navigate(m_Cookies,url);
            window.ShowDialog();
        }

        /// <summary>
        /// JFIF数据头
        /// </summary>
        static readonly byte[] JFIF = new byte[] { 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46 };

        public static Stream GetVerifyImage()
        {
            IPEndPoint endpoint = GetHost();
            RequestArgs request=new RequestArgs()
            {
                Url = "/otsweb/passCodeAction.do?rand=lrand",
                Host="dynamic.12306.cn",
                Accept="image/*",
                Referer="https://dynamic.12306.cn/otsweb/loginAction.do?method=init",
            };
            m_Response=HttpHelper.Get(endpoint,request,m_X509);
            if(m_Response!=null)
            {
                if(m_Response.Header.StartsWith("HTTP/1.1 200"))
                {
                    //先校正保存cookies
                    AdjustCookies();

                    //由于HTTP返回协议使用了 chunked，所以要手动去分析实际需要的内容
                    if (m_Response.Body != null && m_Response.Body.Length > 10)
                    {
                        int index = 0;
                        byte[] head = new byte[10];
                        while (index < m_Response.Body.Length - 10)
                        {
                            Array.Copy(m_Response.Body,index,head,0,head.Length);
                            if (head.SequenceEqual(JFIF))
                            {
                                byte[] buff = new byte[m_Response.Body.Length-index];
                                Array.Copy(m_Response.Body,
                                    index,
                                    buff,0,buff.Length);
                                return new MemoryStream(buff);
                            }
                            index++;
                        }
                    }
                }
            }
            return null;
        }

        public static bool Login(string name, string pass, string verifyCode, out string error)
        {
            error = string.Empty;
            IPEndPoint endpoint = GetHost();
            RequestArgs request=new RequestArgs()
            {
                Url = "/otsweb/loginAction.do?method=login",
                Host="dynamic.12306.cn",
                Accept="text/*",
                Referer="https://dynamic.12306.cn/otsweb/loginAction.do?method=init",
                Cookie = m_Cookies,
                Body = string.Format("loginUser.user_name={0}&nameErrorFocus=&user.password={1}&passwordErrorFocus=&randCode={2}&randErrorFocus=",
                   name,pass,verifyCode)
            };
            m_Response=HttpHelper.Post(endpoint,request,m_X509);
            if (m_Response != null)
            {
                if (m_Response.Header.StartsWith("HTTP/1.1 200"))
                {
                    if (m_Response.Body != null)
                    {
                        string strHtml = Encoding.UTF8.GetString(m_Response.Body);
                        if (strHtml.Contains("我的信息") && strHtml.Contains("用户注销"))
                        {
                            return true;
                        }
                        else if (strHtml.Contains("当前访问用户过多，请稍后重试!"))
                        {
                            error = "当前访问用户过多，请稍后重试!";
                        }
                        else if (strHtml.Contains("请输入正确的验证码！</span>"))
                        {
                            error = "请输入正确的验证码!";
                        }
                        else
                        {
                            error = "各种登录失败，兄弟，理解万岁吧！";
                        }
                    }
                }
                else
                {
                    error = "HTTP响应错误:"+Utility.SplitString(m_Response.Header,
                        "HTTP/1.1 ",
                        " ");
                } 
            }
            else
            {
                error = "超时，主机没有反映！";
            }
            return false;
        }

        static void AdjustCookies()
        {
            m_Cookies = HttpHelper.ParseCookies(m_Response.Header);
        }

        public static bool GetTickets(out string strHtml)
        {
            strHtml = string.Empty;
            IPEndPoint endpoint = GetHost();
            RequestArgs request=new RequestArgs()
            {
                Url = string.Format("/otsweb/order/querySingleAction.do?{0}",
                    Global.MyTicketArgs.ToString()),
                Host="dynamic.12306.cn",
                Accept="text/*",
                Referer = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=init",
                Cookie = m_Cookies,
            };
            m_Response=HttpHelper.Get(endpoint,request,m_X509);
            if (m_Response != null)
            {
                if (m_Response.Header.StartsWith("HTTP/1.1 200"))
                {
                    if (m_Response.Body != null)
                    {
                        strHtml = Encoding.UTF8.GetString(m_Response.Body);
                        return true;
                    }
                }
            }
            return false;
        }

        public static bool Order(Ticket ticket, out string strHtml)
        {
            strHtml = string.Empty;
            IPEndPoint endpoint = GetHost();
            RequestArgs request = new RequestArgs()
            {
                Url = "/otsweb/order/querySingleAction.do?method=submutOrderRequest",
                Host = "dynamic.12306.cn",
                Accept = "text/*",
                Referer = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=init",
                Cookie = m_Cookies,
                Body=ticket.ToString()
            };
            m_Response = HttpHelper.Post(endpoint, request, m_X509);
            if (m_Response != null)
            {
                string location=HttpHelper.ParseLocation(m_Response.Header);
                if (m_Response.Header.StartsWith("HTTP/1.1 302")
                    && location.Contains("confirmPassengerAction.do"))
                {
                    //转向确认购票页面
                    request.Url = location;
                    m_Response = HttpHelper.Get(endpoint, request, m_X509);
                    if (m_Response != null)
                    {
                        if (m_Response.Header.StartsWith("HTTP/1.1 200")
                            && m_Response.Body!=null)
                        {
                            strHtml = Encoding.UTF8.GetString(m_Response.Body);
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        static IPEndPoint GetHost()
        {
            try
            {
                var address = Dns.GetHostAddresses("dynamic.12306.cn");
                if (address.Length > 0)
                {
                    return new IPEndPoint(address[0], 443);
                }
            }
            catch (Exception)
            {
            }
            return new IPEndPoint(IPAddress.Parse("122.228.243.22"), 443);
        }
    }
}
